package drongo.desktop.utils
{
	import flash.geom.Point;

	public class CollisionsHelp
	{
		private static var HELP_POINT0:Point=new Point();
		
		public function CollisionsHelp()
		{
		}
		
		/**
		 * 求旋转后的点坐标
		 * @param angle         角度
		 * @param point         旋转前的坐标点
		 * @param result        
		 */
		public static function  RotationPoint(rad:Number,point:Point,result:Point):Point{
			//角度转弧度
			if(result==null){
				result=new Point();
			}
			result.x = Math.cos(rad) * point.x - Math.sin(rad) * point.y;
			result.y = Math.cos(rad) * point.y + Math.sin(rad) * point.x;
			return result;
		}
		
		/**
		 * 求两个向量之间的夹角
		 * @param av        单位向量
		 * @param bv        单位向量
		 */
		public static function CalculateAngle(av:Point,bv:Point,signed:Boolean=false):Number{
			//cos=a.b/(|a||b|);
			var angle:Number= Math.acos((av.x*bv.x+av.y*bv.y)/(Math.sqrt(av.x*av.x+av.y*av.y)*Math.sqrt(bv.x*bv.x+bv.y*bv.y)));
			if(signed){
				//axb=|a|*|b|*sin(o);
			    var x:Number=Math.asin(av.x*bv.y -av.y*bv.x);
				if(x<0){
					angle=-angle;
				}
			}
			return angle;
		}
		
		private static function  determinant(v1:Number, v2:Number, v3:Number, v4:Number):Number  // 行列式  
		{  
			return (v1*v3-v2*v4);  
		}  
		
		/**
		 * 判断线段是否相交
		 */
		public static function Intersect3(aa:Point, bb:Point, cc:Point, dd:Point) :Boolean
		{  
			var delta:Number = determinant(bb.x-aa.x,dd.x-cc.x, dd.y-cc.y, bb.y-aa.y);  
			if ( delta<=(1e-6) && delta>=-(1e-6) )  // delta=0，表示两线段重合或平行  
			{  
				return false;  
			}  
			var namenda:Number = determinant(dd.x-cc.x, aa.x-cc.x, aa.y-cc.y, dd.y-cc.y) / delta;  
			if ( namenda>1 || namenda<0 )  
			{  
				return false;  
			}  
			var miu:Number = determinant(bb.x-aa.x, aa.x-cc.x, aa.y-cc.y, bb.y-aa.y) / delta;  
			if ( miu>1 || miu<0 )  
			{  
				return false;  
			}  
			return true;  
		}
		/**
		 * 求ab点的垂直向量
		 */
		public static function VerticalVector(a:Point,b:Point,out:Point):void{
			var v:Point=new Point();
			v.x=a.x-b.x;
			v.y=a.y-b.y;
			if(v.x==0&&v.y==0){
				throw new Error("向量为0");
			}
			if(v.x==0){
				out.y=0;
				if(v.y<0){
					out.x=-1;
				}else{
					out.x=1;
				}
				return;
			}
			if(v.y==0){
				out.x=0;
				if(v.x<0){
					out.y=-1;
				}else{
					out.y=1;
				}
				return;
			}
			out.x=-v.y/v.x;
			out.y=1;
		}
		
		/**
		 * 求出垂直向量
		 */
		public static function VerticalVector2(end:Point,start:Point,out:Point):void{
			var red:Number=Math.atan2((end.y-start.y), (end.x-start.x));
			HELP_POINT0.x=0;
			HELP_POINT0.y=1;
			CollisionsHelp.RotationPoint(red,HELP_POINT0,out);
		}
		
		/**
		 * 距离检测
		 */
		public static function DistanceDetection(a:Point,b:Point,dis:Number):Boolean{
			var dx:Number=b.x-a.x;
			var dy:Number=b.y-a.y;
			var dis2:Number=dis*dis;
			return Math.abs(dx*dx+dy*dy)<dis2;
		}
		private static var targetPoint:Point=new Point();
		private static var aPoint:Point=new Point();
		private static var bPoint:Point=new Point();
		/**
		 * 点到线段的距离 
		 * @param P3
		 * @param PA
		 * @param PB
		 * @return 
		 */		
		public static function GetNearestDistance(target:Object,pa:Object, pb:Object):Number
		{   
			targetPoint.x=target.x;
			targetPoint.y=target.y;
			aPoint.x=pa.x;
			aPoint.y=pa.y;
			bPoint.x=pb.x;
			bPoint.y=pb.y;
			
			var a:Number,b:Number,c:Number;   
			a=Point.distance(bPoint,targetPoint);   
			if(a<=0.00001)   
				return 0;   
			b=Point.distance(aPoint,targetPoint);   
			if(b<=0.00001)   
				return 0;
			c=Point.distance(aPoint,bPoint);   
			if(c<=0.00001)   
				return a;//如果PA和PB坐标相同，则退出函数，并返回距离   
			//------------------------------   
			
			
			if(a*a>=b*b+c*c)//--------图3--------   
				return b;   
			if(b*b>=a*a+c*c)//--------图4-------   
				return a;    
			
			//图1   
			var l:Number=(a+b+c)/2;     //周长的一半   
			var s:Number=Math.sqrt(l*(l-a)*(l-b)*(l-c));  //海伦公式求面积   
			return 2*s/c;  
		}
	}
}